<?php
/**
 * Created by PhpStorm.
 * User: HS032
 * Date: 2020/7/21
 * Time: 11:05
 */

namespace pay\modules\frontend\controllers;


use pay\libs\Msg;
use pay\libs\WxPay;
use pay\libs\Tools;
use pay\libs\CheckSign;
use pay\libs\WxPayApi;
use pay\modules\frontend\models\Configuration;
use pay\modules\frontend\models\Order;
use pay\modules\frontend\models\OrderDetails;
use pay\modules\frontend\models\RefundOrderLog;
use pay\plug\CcbMainPay;
use Yii;
use yii\base\Exception;
use yii\log\FileTarget;
use yii\web\Controller;


/*** 微信支付接口类
 * Class WxPayController
 * @package pay\modules\frontend\controllers
 */
class WxPayController extends Controller
{

    public function beforeAction($action)
    {
        $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';
        $allow_origin = array(
            'http://10.9.87.108:8080',
            'http://view.horsevision.cn',
            'http://10.9.87.99:8080',
            'http://www.ysjg.co',
        );
        // P($origin);
        if (in_array($origin, $allow_origin)) {
            header('Access-Control-Allow-Origin:' . $origin);
            header('Access-Control-Allow-Methods:POST,GET');
            header('Access-Control-Allow-Credentials:true');
        }

        return true;
    }



    /*** 后端微信支付接口
     * @return false|string 支付参数
     */
    public function actionPreCreateOrder()
    {
        if (Yii::$app->request->isPost){
            $post = Yii::$app->request->post();
            try {
                $paramsData = (new CheckSign())->checkSignWxPay($post); // 校验签名是否正确
                $orderStatus = $this->createOrder($paramsData); // 添加订单
                if ($orderStatus['code'] != 0){
                    throw new Exception($orderStatus['msg'],99);
                }
                $post = $orderStatus['msg'];
                $wxPayApi = new WxPayApi($post['channelMerId']);
                $result = $wxPayApi->unifiedOrder($post);
                if ($result['code'] === 0){
                    return Tools::showRes(0,'success',$result['msg']);
                }
                throw new Exception($result['msg'],$result['code']);
            }catch (Exception $e){
                $msg = new Msg();
                $msg->insertMsg($e->getCode(),json_encode($post),$e->getMessage());
                return Tools::showRes($e->getCode(),$e->getMessage());
            }


        }
    }

    /*** 新龙小程序 建行支付
     * @return false|string
     */
    public function actionPreCcbis()
    {
        if (Yii::$app->request->isPost){
            try{
                $ccbMainPay = new CcbMainPay();
                $ccbMainPay->paramsData = Yii::$app->request->post();
                $result = $ccbMainPay->sendPay();
                return Tools::showRes(0,'success',$result);
            }catch (Exception $e){
                $msg = new Msg();
                $msg->insertMsg($e->getCode(),json_encode(Yii::$app->request->post()),$e->getMessage());
                return Tools::showRes($e->getCode(),$e->getMessage());
            }
        }
    }
    

    

    /*** 查询订单
     * @return false|string
     */
    public function actionQueryOrder()
    {
        if (Yii::$app->request->isPost){
            $post = Yii::$app->request->post();
            try{
                // 校验签名
                $paramsData = (new CheckSign())->checkSignViewOrder($post);
                $orderModel = new Order();
                $orderInfo = $orderModel->queryOrderInfo($paramsData['appId'],$paramsData['payNo'],2);
                if (!empty($orderInfo)){
                    return Tools::showRes(0,'success',[
                        'orderInfo' => $orderInfo,
                    ]);
                }
                return Tools::showRes(99,'未查询到该订单');
            }catch (Exception $e){
                return Tools::showRes($e->getCode(),$e->getMessage());
            }

        }
    }


    /*** 查询订单
     * @return false|string
     */
    public function actionQueryOrderList()
    {
        if (Yii::$app->request->isPost){
            $post = Yii::$app->request->post();
            try{
                if (empty($post['channel_id']) || empty($post['openid'])){
                    throw new Exception('参数有误');
                }
                // 校验签名
                $orderModel = new OrderDetails();
                $orderInfoList = $orderModel->queryOrderInfoList($post);
                if (!empty($orderInfoList)){
                    return Tools::showRes(0,'success',$orderInfoList);
                }
                return Tools::showRes(99,'未查询到该订单');
            }catch (Exception $e){
                return Tools::showRes($e->getCode(),$e->getMessage());
            }

        }
    }

    /*** 退款接口
     * @return string
     */
    public function actionRefundOrder()
    {
        if (Yii::$app->request->isPost){
            $post = Yii::$app->request->post();
            $msgModel = new Msg();
            try {
                $postData = (new CheckSign())->checkSignRefund($post);

                $orderModel = new Order();
                $orderInfo = $orderModel->queryPayOrderInfo($postData['payUserSerial']);
                if ($orderInfo['pay_status'] != 3){
                    throw new Exception('订单未支付',99);
                }
                if ($postData['refundType'] == 'moon'){
                    $postData['paySerialId'] = $orderInfo['pay_order_sn'];
                    $postData['refundUserSerial'] = 'rf'.Tools::createSn();
                }
                $refuncOrderLogModel = new RefundOrderLog();
                if (!$refund_id = $refuncOrderLogModel->addLog($postData)){
                    if ($refuncOrderLogModel->hasErrors()){
//                        $msgModel->insertMsg('refund-order','40056',json_encode($postData),json_encode($refuncOrderLogModel->getErrors()));
                        $msgModel->insertMsg(40056,json_encode($refuncOrderLogModel->getErrors()),json_encode($postData));
                        throw new Exception('添加退款失败',40056);
                    }else{
                        throw new Exception('添加退款失败',40056);
                    }
                }
                $wxPayApi = new WxPayApi($postData['channelMerId']);

                $result = $wxPayApi->refund($postData);
                $msgModel->insertMsg(400500,json_encode($result,JSON_UNESCAPED_UNICODE),json_encode($postData));
                $refundModel = RefundOrderLog::findOne($refund_id);
                $refundModel->result_params = json_encode($result,JSON_UNESCAPED_UNICODE);
                $refundModel->save(0);
                if ($result['code'] === 0){
                    $orderModels = Order::findOne($orderInfo['oid']);
                    $orderModels->pay_status = 5;
                    $orderModels->ref_order_sn = $postData['refundUserSerial'];
                    $orderModels->save(0);
                    $orderDetailsModel = new OrderDetails();
                    $orderDetailsModel->addRefundInfo($orderInfo['oid'],$postData);
                    $msgModel->insertMsg('000000',json_encode($result,JSON_UNESCAPED_UNICODE),json_encode($postData));
                    return Tools::showRes(0,'success');
                }else{
                    $msgModel->insertMsg(400040,json_encode($result,JSON_UNESCAPED_UNICODE),json_encode($postData));
                    return Tools::showRes(99,$result['msg']);
                }
            }catch (Exception $e){
                return Tools::showRes($e->getCode(),$e->getMessage());
            }

        }
    }
	
	public function actionTest(){
		$paraMap=[
			'aid'=>2,
			'appId'=>1,
			'channelMerId'=>'QZB2020915',
			'nonceStr'=>'1623391014623',
			'payUserId'=>'小程序退款',
			'payUserSerial'=>'4028815179ee94570179eeb1a0080532',
			'refundFee'=>0.01,
			'refundType'=>'sun',
			'signType'=>'MD5',
			'timeStamp'=>1623391014623,
			'totalFee'=>0.01,
			'key'=>'ijgEEtPY31nLov6f1AvLmhrFlQuQzWNS',
		];
		$key = 'exrVhmRG8dO5WZc8iuCgxqIY0i0RZdFI';
		
		
		$buff = "";
		ksort($paraMap);
		foreach ($paraMap as $k => $v) {
		    if (null != $v && "null" != $v && $k != 'sign') {
		        if ($urlEncode) {
		            $v = urlencode($v);
		        }
		        $buff .= $k . "=" . $v . "&";
		    }
		}
		$reqPar = '';
		if (strlen($buff) > 0) {
		    $reqPar = substr($buff, 0, strlen($buff) - 1);
		}
		$sign = strtoupper(md5(base64_encode($reqPar . "&key=" . $key)));
		return $sign;
	}
	
	
	/*** 恐龙园vip退款接口
	     * @return string
	     */
	    public function actionRefundOrderByVip()
	    {
	        if (Yii::$app->request->isPost){
	            $post = Yii::$app->request->post();
	            $msgModel = new Msg();
				
				
				
	            try {
	                $postData = (new CheckSign())->checkSignRefund($post);
	
	                $orderModel = new Order();
	                $orderInfo = $orderModel->queryPayOrderInfoByRemake($postData['payUserSerial']);
	                if ($orderInfo['pay_status'] != 3){
	                    throw new Exception('订单未支付',99);
	                }
	                if ($postData['refundType'] == 'moon'){
	                    $postData['paySerialId'] = $orderInfo['pay_order_sn'];
	                    $postData['refundUserSerial'] = 'rf'.Tools::createSn();
	                }
	                $refuncOrderLogModel = new RefundOrderLog();
	                if (!$refund_id = $refuncOrderLogModel->addLog($postData)){
	                    if ($refuncOrderLogModel->hasErrors()){
	//                        $msgModel->insertMsg('refund-order','40056',json_encode($postData),json_encode($refuncOrderLogModel->getErrors()));
	                        $msgModel->insertMsg(40056,json_encode($refuncOrderLogModel->getErrors()),json_encode($postData));
	                        throw new Exception('添加退款失败',40056);
	                    }else{
	                        throw new Exception('添加退款失败',40056);
	                    }
	                }
	                $wxPayApi = new WxPayApi($postData['channelMerId']);
	
	                $result = $wxPayApi->refund($postData);
	                $msgModel->insertMsg(400500,json_encode($result,JSON_UNESCAPED_UNICODE),json_encode($postData));
	                $refundModel = RefundOrderLog::findOne($refund_id);
	                $refundModel->result_params = json_encode($result,JSON_UNESCAPED_UNICODE);
	                $refundModel->save(0);
	                if ($result['code'] === 0){
	                    $orderModels = Order::findOne($orderInfo['oid']);
	                    $orderModels->pay_status = 5;
	                    $orderModels->ref_order_sn = $postData['refundUserSerial'];
	                    $orderModels->save(0);
	                    $orderDetailsModel = new OrderDetails();
	                    $orderDetailsModel->addRefundInfo($orderInfo['oid'],$postData);
	                    $msgModel->insertMsg('000000',json_encode($result,JSON_UNESCAPED_UNICODE),json_encode($postData));
	                    return Tools::showRes(0,'success');
	                }else{
	                    $msgModel->insertMsg(400040,json_encode($result,JSON_UNESCAPED_UNICODE),json_encode($postData));
	                    return Tools::showRes(99,$result['msg']);
	                }
	            }catch (Exception $e){
	                return Tools::showRes($e->getCode(),$e->getMessage());
	            }
	
	        }
	    }


    public function actionTest()
    {
        $callParams = [
            'appId' => 1,
            'payStatus' => 2,
            'payNo' => 3,
            'orderSn' => 4,
            'payTime' =>5,
            'attach' => 6,
            'nonceStr' => 7,
            'timeStamp' => 8,
            'sign' => '33DC93171607AEDC127F2675C35FAE03',
        ];

        $sign = Tools::computeSign($callParams,'exrVhmRG8dO5WZc8iuCgxqIY0i0RZdFI');
        var_dump($sign);die;
    }


    /*** 生成订单
     * @param $pay_order_sn
     * @param $post
     * @return array|false|string
     */
    private function createOrder($post)
    {
        $orderModel = new Order();
        $orderDetailsModel = new OrderDetails();
        $model = Order::find()->where('mar_order_sn = :msn and app_id = :aid',[':msn' => $post['payNo'],':aid' => $post['appId']])->asArray()->one();

        $msgModel = new Msg();
        $transaction = Yii::$app->db->beginTransaction();
        try{
            if ($model['pay_status'] == 3){
                throw new Exception('该订单已支付');
            }
            if (empty($model)){
                $pay_order_sn = Tools::createSn();  // 支付单号
                $post['pay_order_sn'] = $pay_order_sn;
                if (!$oid = $orderModel->addOrder($post)){
                    if ($orderModel->hasErrors()){
                        $this->recordLogin('99','添加订单失败',json_encode($orderModel->getErrors()));
                        throw new Exception('添加订单失败');
                    }else{
                        throw new Exception('添加订单失败');
                    }
                }
                if (!$orderDetailsModel->addInfo($oid,$post)){
                    if ($orderDetailsModel->hasErrors()){
                        $this->recordLogin('99','添加订单详情失败',json_encode($orderDetailsModel->getErrors()));
                        throw new Exception('添加订单失败');
                    }else{
                        throw new Exception('添加订单失败');
                    }
                }
            }else{
                $post['pay_order_sn'] = $model['pay_order_sn'];
            }
            $transaction->commit();
            return ['code' => 0,'msg' => $post];
        }catch (Exception $e){
            $transaction->rollBack();
            $msgModel->insertMsg('99',json_encode($post),$e->getMessage());
            return ['code' => 99,'msg' => $e->getMessage()];
        }
    }


    protected function recordLogin($code,$msg,$data)
    {
        $log = new FileTarget();
        $log->logFile = Yii::$app->getRuntimePath() . '/wxPay/pay_' . date('Ymd') . '.log';
        $log->messages[] = [
            "[url:{$_SERVER['REQUEST_URI']}],[data:{$code},{$msg},{$data}]",
            1,
            'application',
            time(),
        ];
        $log->export();
    }
}